package pl.alipiec.stockview.master;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.hornetq.core.logging.Logger;

import pl.alipiec.stockview.StockViewException;
import pl.alipiec.stockview.StockViewHelper;

public abstract class Broker {

	private Connection connection = null;
	private InitialContext initialContext = null;
	private Session session;

	private Logger log = Logger.getLogger(getClass());

	/**
	 * Nawiazywanie polaczenia
	 * 
	 * @throws StockViewException
	 */
	public void connect() throws StockViewException {
		templateMethod(new ITemplateCatch<String>() {

			@Override
			public String method() throws Exception {
				initialContext = StockViewHelper.getContext();

				ConnectionFactory cf = (ConnectionFactory) initialContext
						.lookup("/client/ConnectionFactory");

				connection = cf.createConnection();

				session = connection.createSession(false,
						Session.AUTO_ACKNOWLEDGE);

				connection.start();
				return null;
			}
		});
	}

	/**
	 * Zamykanie polaczenia
	 */
	public void closeConnection() {

		if (initialContext != null) {
			try {
				initialContext.close();
			} catch (NamingException e) {
				log.error(e);
				e.printStackTrace();
			}
		}
		if (connection != null) {
			try {
				connection.close();
			} catch (JMSException e) {
				log.error(e);
				e.printStackTrace();
			}
		}
	}

	public MessageProducer getTopicProducer(final String name)
			throws StockViewException {
		return templateMethod(new ITemplateCatch<MessageProducer>() {

			@Override
			public MessageProducer method() throws Exception {
				Topic mainTopic = (Topic) initialContext.lookup(name);
				return session.createProducer(mainTopic);
			}

		});
	}

	public TextMessage createMessage(final Stock stock) throws JMSException {
		return session.createTextMessage(stock.toJSON());
	}

	public void logError(Object err) {
		log.error(err);
	}

	public void logInfo(Object info) {
		log.info(info);
	}

	private <T> T templateMethod(ITemplateCatch<T> item)
			throws StockViewException {
		try {
			return item.method();
		} catch (Exception e) {
			e.printStackTrace();
			throw new StockViewException(e);
		}
	}

}
